/*
 * This file Copyright (c) 2015. Walle.
 * (http://www.wallellen.com). All rights reserved.
 *
 *
 * This file is dual-licensed under both the
 * Walle Agreement (WA) and the GNU General Public License.
 * You may elect to use one or the other of these licenses.
 *
 * This file is distributed in the hope that it will be
 * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
 * Redistribution, except as permitted by whichever of the GPL
 * or WA you select, is prohibited.
 *
 * 1. For the GPL license (GPL), you can redistribute and/or
 * modify this file under the terms of the GNU General
 * Public License, Version 3, as published by the Free Software
 * Foundation.  You should have received a copy of the GNU
 * General Public License, Version 3 along with this program;
 * if not, write to the Free Software Foundation, Inc., 51
 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * 2. For the Walle Agreement (WA), this file
 * and the accompanying materials are made available under the
 * terms of the WA which accompanies this distribution, and
 * is available at http://www.wallellen.com/agreement.html
 *
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 */

package com.wallellen.knowledge.doc.server.impl;

import com.wallellen.core.auth.domain.LoginUser;
import com.wallellen.core.sql.query.DBRule;
import com.wallellen.core.time.TimeTool;
import com.wallellen.knowledge.doc.dao.DocfileDaoInter;
import com.wallellen.knowledge.doc.dao.RfDoctextfileDaoInter;
import com.wallellen.knowledge.doc.domain.Docfile;
import com.wallellen.knowledge.doc.domain.RfDocTextFile;
import com.wallellen.knowledge.doc.server.FileManagerInter;
import com.wallellen.knowledge.doc.server.commons.DocFiles;
import com.wallellen.knowledge.doc.server.commons.DocumentConfig;
import com.wallellen.parameter.ParamService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class FileManagerImpl implements FileManagerInter {
    @Resource
    private DocfileDaoInter docfileDao;
    @Resource
    private RfDoctextfileDaoInter rfDoctextfileDao;
    private static final Logger log = LoggerFactory.getLogger(FileManagerImpl.class);

    @Override
    @Transactional
    public String saveFile(File file, FILE_TYPE type, String title, LoginUser user) {
        String exName = DocFiles.getExName(title);
        if (exName.trim().toUpperCase().replace(".", "").equals("ZIP")) {
            type = FILE_TYPE.RESOURCE_ZIP;
        }
        String userId = null;
        String userName = null;
        if (user == null || user.getName() == null) {
            userId = "none";
            userName = "none";
        } else {
            userId = user.getId();
            userName = user.getName();
        }
        Docfile docfile = new Docfile(DocFiles.generateDir(),
                UUID.randomUUID().toString().replaceAll("-", ""), type.getValue(), title, file.getName(),
                TimeTool.getTimeDate14(), TimeTool.getTimeDate14(), userName, userId, userName, userId, "0", null,
                exName, Float.valueOf(String.valueOf(file.length())));
        if (user == null || user.getName() == null) {
            docfile.setCusername("none");
            docfile.setEusername("none");
        }
        DocFiles.copyFile(file, DocFiles.getFileDirPath() + docfile.getDir());
        docfile = docfileDao.insertEntity(docfile);

        return docfile.getId();
    }

    public String saveFile(InputStream inStream, String filename, String title, FILE_TYPE type, LoginUser user) {
        String exName = DocFiles.getExName(title);
        if (exName.trim().toUpperCase().replace(".", "").equals("ZIP")) {
            type = FILE_TYPE.RESOURCE_ZIP;
        }
        String userId = null;
        String userName = null;
        if (user == null || user.getName() == null) {
            userId = "none";
            userName = "none";
        } else {
            userId = user.getId();
            userName = user.getName();
        }
        Docfile docfile = new Docfile(DocFiles.generateDir(),
                UUID.randomUUID().toString().replaceAll("-", ""), type.getValue(), title, filename,
                TimeTool.getTimeDate14(), TimeTool.getTimeDate14(), userName, userId, userName, userId, "0", null,
                exName, Float.valueOf(String.valueOf(0)));
        if (user == null || user.getName() == null) {
            docfile.setCusername("none");
            docfile.setEusername("none");
        }
        long length = DocFiles.saveFile(inStream, filename,
                DocumentConfig.getString("config.doc.dir") + docfile.getDir());
        docfile.setLen(Float.valueOf(String.valueOf(length)));
        docfile = docfileDao.insertEntity(docfile);
        return docfile.getId();
    }

    @Override
    public String getFileURL(String fileid) {
        String url = DocumentConfig.getString("config.doc.download.url") + fileid;
        return url;
    }

    @Override
    @Transactional
    public Docfile getFile(String fileid) {
        Docfile file = docfileDao.getEntity(fileid);
        if (file == null) {
            return null;
        }
        file.setFile(new File(DocFiles.getFileDirPath() + File.separator + file.getDir() + file.getFilename()));
        // 如果文件是大小是0的话就刷新文件大小
        if (file.getLen() == 0) {
            file.setLen(Float.valueOf(String.valueOf(file.getFile().length())));
            if (file.getLen() == 0) {
                file.setLen(Float.valueOf(-1));
            }
            docfileDao.editEntity(file);
        }
        return file;
    }

    @Override
    public File getNoneImg() {
        String imgpath = ParamService.getInstance().getParameter("config.doc.none.img.path");
        return new File(ParamService.getInstance().getParameter("farm.constant.webroot.path") + File.separator
                + imgpath.replaceAll("\\\\", File.separator).replaceAll("//", File.separator));
    }

    @Override
    @Transactional
    public void submitFile(String fileId) {
        Docfile file = docfileDao.getEntity(fileId);
        file.setPstate("1");
        file.setEtime(TimeTool.getTimeDate14());
        docfileDao.editEntity(file);
    }

    @Override
    @Transactional
    public void cancelFile(String fileId) {
        Docfile file = docfileDao.getEntity(fileId);
        if (file == null) {
            return;
        }
        file.setPstate("0");
        docfileDao.editEntity(file);
    }

    @Override
    @Transactional
    public void delFile(String fileId, LoginUser user) {
        Docfile docfile = docfileDao.getEntity(fileId);
        if (docfile == null) {
            return;
        }
        File file = this.getFile(fileId).getFile();
        docfileDao.deleteEntity(docfile);
        if (file.exists()) {
            if (file.delete()) {
                log.info("删除成功！");
            } else {
                log.error("文件删除失败,未能删除请手动删除！");
            }
        }
    }

    @Override
    @Transactional
    public Docfile openFile(String exname, String content, LoginUser user) {
        FILE_TYPE type = FILE_TYPE.OHTER;
        String filename = UUID.randomUUID().toString();
        Docfile docfile = new Docfile(DocFiles.generateDir(),
                UUID.randomUUID().toString().replaceAll("-", ""), type.getValue(), filename + "." + exname,
                filename + ".tmp", TimeTool.getTimeDate14(), TimeTool.getTimeDate14(), user.getName(), user.getId(),
                user.getName(), user.getId(), "0", content, exname, Float.valueOf(0));

        File file = new File(DocFiles.getFileDirPath() + docfile.getDir() + File.separator + docfile.getFilename());
        try {
            if (!file.createNewFile()) {
                throw new RuntimeException("文件创建失败!");
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        docfile = docfileDao.insertEntity(docfile);
        docfile.setFile(file);
        return docfile;
    }

    @Override
    @Transactional
    public void addFileForDoc(String docid, String fileId, LoginUser user) {
        rfDoctextfileDao.insertEntity(new RfDocTextFile(docid, fileId));
    }

    @Override
    @Transactional
    public void delFileForDoc(String docid, String fileId, LoginUser user) {
        List<DBRule> list = new ArrayList<DBRule>();
        list.add(new DBRule("FILEID", fileId, "="));
        list.add(new DBRule("DOCID", docid, "="));
        rfDoctextfileDao.deleteEntitys(list);
    }

    @Override
    public List<Docfile> getAllFileForDoc(String docid) {
        List<Docfile> refiles = docfileDao.getEntityByDocId(docid);
        for (Docfile file : refiles) {
            file = getFile(file.getId());
        }
        return refiles;
    }

    @Override
    public List<Docfile> getAllTypeFileForDoc(String docid, String exname) {
        List<Docfile> refiles = docfileDao.getEntityByDocId(docid);
        List<Docfile> newrefiles = new ArrayList<>();
        for (Docfile file : refiles) {
            if (file.getExname().toUpperCase().equals(exname.toUpperCase())) {
                file = getFile(file.getId());
                newrefiles.add(file);
            }
        }
        return newrefiles;
    }

    @Override
    public boolean containFileByDoc(String docid, String fileId) {
        List<Docfile> list = docfileDao.getEntityByDocId(docid);
        for (Docfile node : list) {
            if (node.getId().equals(fileId)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void delAllFileForDoc(String docid, String exname, LoginUser aloneUser) {
        List<Docfile> refiles = docfileDao.getEntityByDocId(docid);
        for (Docfile file : refiles) {
            if (file.getExname().toUpperCase().equals(exname.toUpperCase())) {
                delFileForDoc(docid, file.getId(), aloneUser);
            }
        }

    }

    @Override
    @Transactional
    public void delFileForDoc(String docid, LoginUser user) {
        List<DBRule> list = new ArrayList<DBRule>();
        list.add(new DBRule("DOCID", docid, "="));
        rfDoctextfileDao.deleteEntitys(list);
    }
}
